package com.sanjin.service.impl;

import com.sanjin.entity.ParkOrder;
import com.sanjin.entity.WxMiniUser;
import com.sanjin.enums.OrderStatusEnum;
import com.sanjin.enums.ParkSpaceStatusEnum;
import com.sanjin.exception.MyException;
import com.sanjin.repository.ParkOrderRepository;
import com.sanjin.service.ParkOrderService;
import com.sanjin.service.ParkSpaceService;
import com.sanjin.service.WxMiniUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.List;

/**
 * @description:
 * @author: sanjin
 * @date: 2019/5/8 12:42
 */
@Service
public class ParkOrderServiceImpl implements ParkOrderService {

    @Autowired
    private ParkOrderRepository orderRepository;

    @Autowired
    private WxMiniUserService wxMiniUserService;

    @Autowired
    private ParkSpaceService parkSpaceService;

    @Transactional(propagation = Propagation.REQUIRED)
    @Override
    public ParkOrder createOrder(ParkOrder order) {
        if (order.getId() != null)
            throw new MyException("[创建订单] 不能含有id");
        if (order.getWxMiniUserId() == null)
            throw new MyException("[创建订单] 必须含有wxMiniUserId");
        // 新建订单默认为待支付状态
        order.setStatus(OrderStatusEnum.WAIT_PAY.code);
        return orderRepository.save(order);
    }

    @Transactional(propagation = Propagation.REQUIRED)
    @Override
    public ParkOrder payOrder(Integer orderId, Integer wxMiniUserId) {
        ParkOrder order = orderRepository.queryOrderById(orderId);
        WxMiniUser wxMiniUser = wxMiniUserService.queryWxMiniUserByWxMiniUserId(wxMiniUserId);
        if (order == null)
            throw new MyException("[支付订单] 订单不存在");
        if (wxMiniUser == null)
            throw new MyException("[支付订单] 支付用户id不正确");
        if (!order.getWxMiniUserId().equals(wxMiniUserId)) {
            throw new MyException("[支付订单] 下单用户必须与支付用户为同一用户");
        }
        if (order.getStatus().equals(OrderStatusEnum.ALREADY_CANCEL.code)) {
            throw new MyException("[支付订单] 改订单已经取消，不能够再进行支付");
        }
        if (order.getStatus().equals(OrderStatusEnum.ALREADY_PAY.code)) {
            throw new MyException("[支付订单] 改订单已经支付，不能够再进行支付");
        }

        // 进行支付

        // 计算积分
        BigDecimal userBonusPoints = wxMiniUser.getBonusPoints();
        BigDecimal requireBonusPoints = order.getAmount();
        if (userBonusPoints.compareTo(requireBonusPoints) < 0)
            throw new MyException("[支付订单] 您的积分不足,需要: " + requireBonusPoints + ",还差: " + requireBonusPoints.subtract(userBonusPoints));
        BigDecimal rest = userBonusPoints.subtract(requireBonusPoints);

        // 跟新用户积分
        wxMiniUser.setBonusPoints(rest);
        wxMiniUserService.updateWxMiniUser(wxMiniUser);

        // 更新订单状态为已支付
        order.setStatus(OrderStatusEnum.ALREADY_PAY.code);
        ParkOrder save = orderRepository.save(order);

        // 跟新该车位的状态为 "空闲"
        // parkSpaceService.changeParkSpaceStatus(order.getParkSpaceId(), ParkSpaceStatusEnum.IDLE.code);

        return save;
    }

    @Transactional(propagation = Propagation.REQUIRED)
    @Override
    public ParkOrder cancelOrder(Integer orderId, Integer wxMiniUserId) {
        ParkOrder order = orderRepository.queryOrderById(orderId);
        if (order == null)
            throw new MyException("[支付订单] 订单不存在");
        if (!order.getWxMiniUserId().equals(wxMiniUserId)) {
            throw new MyException("[支付订单] 下单用户必须与支付用户为同一用户");
        }

        // 更新订单状态为取消
        order.setStatus(OrderStatusEnum.ALREADY_CANCEL.code);
        ParkOrder save = orderRepository.save(order);
        return save;
    }

    @Transactional(propagation = Propagation.SUPPORTS)
    @Override
    public List<ParkOrder> getAllOrders() {
        return orderRepository.findAll();
    }

    @Transactional(propagation = Propagation.SUPPORTS)
    @Override
    public ParkOrder queryOrderByOrderId(Integer orderId) {
        return orderRepository.queryOrderById(orderId);
    }

    @Transactional(propagation = Propagation.SUPPORTS)
    @Override
    public ParkOrder queryNonPayOrderByWxMiniUserId(Integer wxMiniUserId) {
        ParkOrder parkOrder = orderRepository.queryParkOrderByWxMiniUserIdAndStatus(wxMiniUserId, OrderStatusEnum.WAIT_PAY.code);
        return parkOrder;
    }
}
